
class_name PreparePlan
extends ColorRect




# unit 信息
@onready var unit_info_icon = $CR/UnitInfo/InfoCR/IconCR/Icon
@onready var unit_info_info = $CR/UnitInfo/InfoCR/Info
@onready var unit_info_hpep = $CR/UnitInfo/InfoCR/HPEP
@onready var unit_info_name = $CR/UnitInfo/InfoCR/Name
@onready var unit_info_skill = $CR/UnitInfo/SkillInfo/Info
# 出战人数显示
@onready var info_number = $CR/InfoCR/Number
# 单位列表
@onready var unit_list_scroll = $CR/UnitList/Scroll
@onready var unit_list_temp = $CR/UnitList/TempUnitItem
@onready var unit_list_vbox = $CR/UnitList/Scroll/VBox
# 按钮选项
@onready var items = [$Items/HBox/Go, $Items/HBox/Observe]
# 下标
@onready var pointer = $Pointer

# 出击! 开始游戏
signal depart_signal
# 添加 unit
signal add_unit_signal
# 删除 unit
signal remove_unit_signal

# 状态枚举
enum PrepareMode {
	UNIT_LIST,
	BTNS
}

# 出击人数
# 最大出击人数可以在检查器设置
var depart_current_number: int = 0
@export var depart_max_number: int = 0

# 指针与当前的项
var pointer_unit: int = 0
var pointer_btn: int = 0
var pointer_mode: PrepareMode = PrepareMode.UNIT_LIST
var current_unit_item: TemplateSelectItem = null
var current_btn_item: TemplateSelectItem = null

# 是否是观察状态以及是否可切换
var is_observe: bool = false
var is_switch: bool = false

var unit_items: Array = []




func _ready() -> void:
	# 因为是键盘操作，所以不希望显示滚动条，这里将滚动条设置为透明的
	unit_list_scroll.get_h_scroll_bar().modulate.a = 0
	unit_list_scroll.get_v_scroll_bar().modulate.a = 0




func _process(delta: float) -> void:
	info_number.text = "出战人数:" + str(depart_current_number) + "/" + str(depart_max_number)




# 开始
func start(_units: Array[Unit]) -> void:
	# 复制显示模板并设置模板信息
	for unit in _units:
		var temp = unit_list_temp.duplicate()
		temp.save_object = unit
		unit_list_vbox.add_child(temp)
		var icon = temp.get_node("IconCR/Icon")
		icon.texture = load(unit.profile_photo)
		temp.set_info_text(unit.property.unit_name)
		temp.show()
	# 将构建的所有TempUnitItem全部保存到unit_items中
	unit_items.append_array(unit_list_vbox.get_children())
	
	# 初始化
	current_unit_item = unit_items[pointer_unit]
	show_unit_info(current_unit_item)
	show_skill_info(current_unit_item)
	# 设置下标的全局位置与大小与当前项贴合
	pointer.set_global_position(current_unit_item.global_position - Vector2(8, 8))
	pointer.set_size(current_unit_item.size)




# 显示 unit 信息
func show_unit_info(_temp: TemplateSelectItem) -> void:
	var unit: Unit = _temp.save_object
	var property: UnitProperty = unit.property
	
	unit_info_name.text = \
		property.unit_name + ("（出战）" if _temp.is_select else "（未出战）")
	
	unit_info_hpep.text = \
		"HP:" + str(property.current_hp) + \
		"/" + str(property.hp) + \
		"\nEP:" + str(property.current_ep) + \
		"/" + str(property.ep)
	
	unit_info_info.text = \
		"普通攻击:" + str(property.ap_ordinary) + \
		"\t\t特殊攻击:" + str(property.ap_special) + \
		"\n普通抗性:" + str(property.dp_ordinary) + \
		"\t\t特殊抗性:" + str(property.dp_special) + \
		"\n优先度:" + str(property.priority) + \
		"\t\t速度:" + str(property.sp) + \
		"\nHP自然恢复:" + str(property.hp_recover) + \
		"/" + str(property.hp_cycle) + \
		"\tEP自然恢复:" + str(property.ep_recover) + \
		"/" + str(property.ep_cycle)
	
	unit_info_icon.texture = load(unit.profile_photo)




# 设置移动
func _input(_event: InputEvent) -> void:
	# 是观察模式就只判断是否是 switch
	if is_observe:
		if _event.is_action_pressed("action_switch"):
			is_switch = not is_switch
			if is_switch:
				pointer.show()
			else:
				pointer.hide()
			return
		
		# 如果是切换模式
		if is_switch:
			_btn_list_move(_event)
			get_viewport().set_input_as_handled()
			return
		
		return
	
	# 阻止输入事件传播
	get_viewport().set_input_as_handled()
	
	# 切换
	if _event.is_action_pressed("action_switch"):
		# 如果是观察就直接返回
		if is_observe: return
		
		if pointer_mode == PrepareMode.UNIT_LIST:
			pointer_mode = PrepareMode.BTNS
			current_unit_item = null
			current_btn_item = items[pointer_btn]
			pointer.set_global_position(current_btn_item.global_position)
			pointer.set_size(current_btn_item.size)
		
		else:
			pointer_mode = PrepareMode.UNIT_LIST
			current_btn_item = null
			current_unit_item = unit_items[pointer_unit]
			pointer.set_global_position(current_unit_item.global_position)
			pointer.set_size(current_unit_item.size)
		
		return
	
	# 根据模式对事件进行不同的处理
	match pointer_mode:
		PrepareMode.UNIT_LIST:
			_unit_list_move(_event)
		PrepareMode.BTNS:
			_btn_list_move(_event)




func __point_unit_move() -> void:
	# 显示信息
	show_unit_info(current_unit_item)
	show_skill_info(current_unit_item)
	# 设置 scroll 偏移
	unit_list_scroll.scroll_vertical = (current_unit_item.position.y + current_unit_item.size.y) - (unit_list_scroll.size.y / 2)
	unit_list_scroll.scroll_horizontal = 0
	# 为了防止下面的方法获取的位置不对，需要先等待一帧再设置位置
	await get_tree().process_frame
	pointer.set_global_position(current_unit_item.global_position)




## unit 列表移动
func _unit_list_move(_event: InputEvent) -> void:
	if _event.is_action_pressed("pointer_down", true):
		if pointer_unit + 1 < unit_items.size():
			pointer_unit += 1
			current_unit_item = unit_items[pointer_unit]
			__point_unit_move()
	
	elif _event.is_action_pressed("pointer_up", true):
		if pointer_unit - 1 > -1:
			pointer_unit -= 1
			current_unit_item = unit_items[pointer_unit]
			__point_unit_move()
	
	# 确认事件
	elif _event.is_action_pressed("action_confirm"):
		# 判断当前 unit 是否是选中的
		# 如果是选中就取消选中
		if current_unit_item.is_select:
			current_unit_item.set_select(false)
			depart_current_number -= 1
			show_unit_info(current_unit_item)
			show_skill_info(current_unit_item)
			emit_signal("remove_unit_signal", current_unit_item.save_object)
		
		else:
			# 如果人数没有超标
			if depart_current_number < depart_max_number:
				current_unit_item.set_select(true)
				depart_current_number += 1
				show_unit_info(current_unit_item)
				show_skill_info(current_unit_item)
				emit_signal("add_unit_signal", current_unit_item.save_object)




## 按钮列表移动
func _btn_list_move(_event: InputEvent) -> void:
	if _event.is_action_pressed("pointer_down"):
		if pointer_btn + 1 < items.size():
			pointer_btn += 1
			current_btn_item = items[pointer_btn]
			pointer.set_global_position(current_btn_item.global_position)
	
	elif _event.is_action_pressed("pointer_up"):
		if pointer_btn - 1 > -1:
			pointer_btn -= 1
			current_btn_item = items[pointer_btn]
			pointer.set_global_position(current_btn_item.global_position)
	
	# 确认事件
	elif _event.is_action_pressed("action_confirm"):
		match current_btn_item.get_info_text():
			"出击":
				if depart_current_number > 0:
					emit_signal("depart_signal")
			
			"观察":
				get_node("CR").hide()
				color.a = 0
				is_observe = true
				is_switch = false
				$Items/Key.show()
				pointer.hide()
				current_btn_item.set_info_text("显示面板")
			
			"显示面板":
				get_node("CR").show()
				color.a = 1
				is_observe = false
				is_switch = false
				$Items/Key.hide()
				pointer.show()
				current_btn_item.set_info_text("观察")




## 重置状态
## 预备用来在游戏的中途对该面板二次调用
func reset() -> void:
	get_node("CR").show()
	pointer.show()
	$Items/Key.hide()
	items[1].set_info_text("观察")
	is_observe = false
	is_switch = false
	color.a = 1




# 显示技能信息
func show_skill_info(_temp: TemplateSelectItem) -> void:
	var unit: Unit = _temp.save_object
	var skills = unit.skill.skills
	unit_info_skill.text = ""
	for skill in skills:
		unit_info_skill.text += unit.skill.get_node(skill).skill_describe
		unit_info_skill.text += "\n----\n"
